home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Languages / MacGofer 0.22d / MacGofer Sources / runtime.c < prev    next >
Encoding:
Text File  |  1994-01-06  |  35.6 KB  |  658 lines  |  [TEXT/MPS ]

  1. /* --------------------------------------------------------------------------
  2.  * runtime.c:   Copyright (c) Mark P Jones 1991-1993.   All rights reserved.
  3.  *              See goferite.h for details and conditions of use etc...
  4.  *        Gofer Compiler version 1.00 January 1992
  5.  *              Gofer version 2.28 January 1993
  6.  *
  7.  * Runtime system for compiled Gofer programs ... uses a considerably
  8.  * simplified runtime system than required in the full interpreter.
  9.  * ------------------------------------------------------------------------*/
  10.  
  11. #define  NEED_MATH
  12. #include "gofc.h"
  13.  
  14. /* --------------------------------------------------------------------------
  15.  * Static data areas:
  16.  * ------------------------------------------------------------------------*/
  17.  
  18. static  int   keep_argc;        /* keep record of command line       */
  19. static  char  **keep_argv;        /* arguments               */
  20.  
  21. static  Cell  consCharArray[NUM_CHARS];    /* array of ((:) c) for each char c*/
  22.  
  23. static  Cell  resps = 0;        /* pointer to list of responses       */
  24.  
  25. /* --------------------------------------------------------------------------
  26.  * Local function prototypes:
  27.  * ------------------------------------------------------------------------*/
  28.  
  29. static Void   evalString    Args((Cell));
  30.  
  31. static Cell   openFile        Args((String));
  32. static Void   evalFile        Args((Cell));
  33. static Void   closeFile        Args((Int));
  34.  
  35. static Void   dialogue        Args((Cell));
  36. static Void   readFile        Args((Void));
  37. static Void   writeFile        Args((Void));
  38. static Void   appendFile    Args((Void));
  39. static Void   readChan        Args((Void));
  40. static Void   appendChan    Args((Void));
  41. static FILE   *validOutChannel    Args((String));
  42. static Void   echo        Args((Void));
  43. static Void   getArgs        Args((Void));
  44. static Void   getProgName    Args((Void));
  45. static Void   getEnv        Args((Void));
  46. static Void   outputString    Args((FILE *,Cell));
  47. static String evalName        Args((Cell));
  48.  
  49. static Int    compare        Args((Void));
  50.  
  51. static Void   primInit        Args((Void));
  52. static Void   primMark        Args((Void));
  53.  
  54. static sigProto(onBreak);
  55.  
  56. static Void   abandon        Args((String)----------------------------------------------------------
  57.  * Integer arithmetic primitives:
  58.  * ------------------------------------------------------------------------*/
  59.  
  60. static comb2(pr_PlusInt)        /* integer addition primitive       */
  61. {   Int x;
  62.     eval(offset(2));
  63.     x = whnfInt;
  64.     eval(offset(1));
  65.     heap(1);
  66.     update(0,mkInt(x+whnfInt));
  67.     ret();
  68. }
  69. End
  70.  
  71. static comb2(pr_MinusInt)        /* integer subtraction primitive   */
  72. {   Int x;
  73.     eval(offset(2));
  74.     x = whnfInt;
  75.     eval(offset(1));
  76.     heap(1);
  77.     update(0,mkInt(x-whnfInt));
  78.     ret();
  79. }
  80. End
  81.  
  82. static comb2(pr_MulInt)            /* integer multiplication primitive*/
  83. {   Int x;
  84.     eval(offset(2));
  85.     x = whnfInt;
  86.     eval(offset(1));
  87.     heap(1);
  88.     update(0,mkInt(x*whnfInt));
  89.     ret();
  90. }
  91. End
  92.  
  93. static comb2(pr_DivInt)            /* integer division primitive       */
  94. {   Int x,y;                /* truncate towards -ve infinity   */
  95.     eval(offset(2));
  96.     x = whnfInt;
  97.     eval(offset(1));
  98.     if (whnfInt==0)
  99.     abandon("division by zero");
  100.     heap(1);
  101.     y = x%whnfInt;
  102.     x = x/whnfInt;
  103.     if ((y<0 && whnfInt>0) || (y>0 && whnfInt<0))
  104.     x--;
  105.     update(0,mkInt(x));
  106.     ret();
  107. }
  108. End
  109.  
  110. static comb2(pr_QuotInt)        /* integer division primitive       */
  111. {   Int x;                /* truncated towards zero       */
  112.     eval(offset(2));
  113.     x = whnfInt;
  114.     eval(offset(1));
  115.     if (whnfInt==0)
  116.     abandon("division by zero");
  117.     heap(1);
  118.     update(0,mkInt(x/whnfInt));
  119.     ret();
  120. }
  121. End
  122.  
  123. static comb2(pr_ModInt)            /* integer modulo primitive       */
  124. {   Int x,y;
  125.     eval(offset(2));
  126.     x = whnfInt;
  127.     eval(offset(1));
  128.     if (whnfInt==0)
  129.     abandon("division by zero");
  130.     heap(1);
  131.     y = x%whnfInt;            /* "... the modulo having the sign */
  132.     if ((y<0 && whnfInt>0) ||        /*           of the divisor ..." */
  133.     (y>0 && whnfInt<0)) {        /* See definition on p.81 of       */
  134.     update(0,mkInt(y+whnfInt));    /* Haskell report...           */
  135.     }
  136.     else {
  137.     update(0,mkInt(y));
  138.     }
  139.     ret();
  140. }
  141. End
  142.  
  143. static comb2(pr_RemInt)            /* integer remainder primitive       */
  144. {   Int x;
  145.     eval(offset(2));            /* div and rem satisfy:           */
  146.     x = whnfInt;            /* (x `div` y)*y+(x `rem` y) == x  */
  147.     eval(offset(1));            /* which is exactly the property   */
  148.     if (whnfInt==0)            /* described in K&R 2:           */
  149.     abandon("division by zero");    /*      (a/b)*b + a%b == a       */
  150.     heap(1);
  151.     update(0,mkInt(x%whnfInt));
  152.     ret();
  153. }
  154. End
  155.  
  156. static comb1(pr_NegInt)            /* integer negation primitive       */
  157.     eval(offset(1));
  158.     heap(1);
  159.     update(0,mkInt(-whnfInt));
  160.     ret();
  161. End
  162.  
  163. /* --------------------------------------------------------------------------
  164.  * Coercion primitives:
  165.  * ------------------------------------------------------------------------*/
  166.  
  167. static comb1(pr_CharToInt)        /* character to integer conversion */
  168.     eval(offset(1));
  169.     heap(1);
  170.     update(0,mkInt(charOf(whnf)));
  171.     ret();
  172. End
  173.  
  174. static comb1(pr_IntToChar)        /* integer to character conversion */
  175.     eval(offset(1));
  176.     if (whnfInt<0 || whnfInt>=NUM_CHARS)
  177.     abandon("character out of range");
  178.     update(0,mkChar(whnfInt));
  179.     ret();
  180. End
  181.  
  182. static comb1(pr_IntToFloat)        /* integer to float primitive       */
  183.     eval(offset(1));
  184.     heap(1);
  185.     update(0,mkFloat((Float)(whnfInt)));
  186.     ret();
  187. End
  188.  
  189. /* --------------------------------------------------------------------------
  190.  * Float arithmetic primitives:
  191.  * ------------------------------------------------------------------------*/
  192.  
  193. static comb2(pr_PlusFloat)        /* float addition primitive       */
  194. {   Float x;
  195.     eval(offset(2));
  196.     x = floatOf(whnf);
  197.     eval(offset(1));
  198.     heap(1);
  199.     update(0,mkFloat(x+floatOf(whnf)));
  200.     ret();
  201. }
  202. End
  203.  
  204. static comb2(pr_MinusFloat)        /* float subtraction primitive       */
  205. {   Float x;
  206.     eval(offset(2));
  207.     x = floatOf(whnf);
  208.     eval(offset(1));
  209.     heap(1);
  210.     update(0,mkFloat(x-floatOf(whnf)));
  211.     ret();
  212. }
  213. End
  214.  
  215. static comb2(pr_MulFloat)        /* float multiplication primitive  */
  216. {   Float x;
  217.     eval(offset(2));
  218.     x = floatOf(whnf);
  219.     eval(offset(1));
  220.     heap(1);
  221.     update(0,mkFloat(x*floatOf(whnf)));
  222.     ret();
  223. }
  224. End
  225.  
  226. static comb2(pr_DivFloat)        /* float division primitive       */
  227. {   Float x;
  228.     eval(offset(2));
  229.     x = floatOf(whnf);
  230.     eval(offset(1));
  231.     if (floatOf(whnf)==0)
  232.     abandon("float division by zero");
  233.     heap(1);
  234.     update(0,mkFloat(x/floatOf(whnf)));
  235.     ret();
  236. }
  237. End
  238.  
  239. static comb1(pr_NegFloat)        /* float negation primitive       */
  240.     eval(offset(1));
  241.     heap(1);
  242.     update(0,mkFloat(-floatOf(whnf)));
  243.     ret();
  244. End
  245.  
  246. #if HAS_FLOATS
  247. #define FPRIM(n,f)        static comb1(n)                    \
  248.                     eval(offset(1));                \
  249.                     heap(1);                    \
  250.                     update(0,safeMkFloat(f(floatOf(whnf))));\
  251.                     ret();                    \
  252.                 End
  253. FPRIM(pr_SinFloat,sin)            /* floating point math prims       */
  254. FPRIM(pr_CosFloat,cos)
  255. FPRIM(pr_TanFloat,tan)
  256. FPRIM(pr_AsinFloat,asin)
  257. FPRIM(pr_AcosFloat,acos)
  258. FPRIM(pr_AtanFloat,atan)
  259. FPRIM(pr_LogFloat,log)            /* one day, I should expand these  */
  260. FPRIM(pr_Log10Float,log10)        /* to ensure the argument is > 0   */
  261. FPRIM(pr_ExpFloat,exp)
  262. FPRIM(pr_SqrtFloat,sqrt)
  263. #undef FPRIM
  264.  
  265. static comb2(pr_Atan2Float)        /* arc tan with quadrant info       */
  266. {   Float x;
  267.     eval(offset(2));
  268.     x = floatOf(whnf);
  269.     eval(offset(1));
  270.     heap(1);
  271.     update(0,mkFloat(atan2(x,floatOf(whnf))));
  272.     ret();
  273. }
  274. End
  275.  
  276. static comb1(pr_FloatToInt)        /* convert floating point to int   */
  277.     eval(offset(1));            /* :: Float -> Int           */
  278.     heap(1);
  279.     update(0,mkFloat((Float)(whnfInt)));
  280.     ret();
  281. End
  282. #endif
  283.  
  284. /* --------------------------------------------------------------------------
  285.  * Comparison primitives:
  286.  * ------------------------------------------------------------------------*/
  287.  
  288. static comb2(pr_EqInt)            /* integer equality primitive       */
  289. {   Int x;
  290.     eval(offset(2));
  291.     x = whnfInt;
  292.     eval(offset(1));
  293.     update(0,(x==whnfInt ? cfunTrue : cfunFalse));
  294.     ret();
  295. }
  296. End
  297.  
  298. static comb2(pr_LeInt)            /* integer <= primitive           */
  299. {   Int x;
  300.     eval(offset(2));
  301.     x = whnfInt;
  302.     eval(offset(1));
  303.     update(0,(x<=whnfInt ? cfunTrue : cfunFalse));
  304.     ret();
  305. }
  306. End
  307.  
  308. static comb2(pr_EqChar)            /* character equality primitive       */
  309. {   Cell x;
  310.     eval(offset(2));
  311.     x = whnf;
  312.     eval(offset(1));
  313.     update(0,(x==whnf ? cfunTrue : cfunFalse));
  314.     ret();
  315. }
  316. End
  317.  
  318. static comb2(pr_LeChar)            /* character <= primitive       */
  319. {   Cell x;
  320.     eval(offset(2));
  321.     x = whnf;
  322.     eval(offset(1));
  323.     update(0,(x<=whnf ? cfunTrue : cfunFalse));
  324.     ret();
  325. }
  326. End
  327.  
  328. static comb2(pr_EqFloat)        /* float equality primitive       */
  329. {   Float x;
  330.     eval(offset(2));
  331.     x = floatOf(whnf);
  332.     eval(offset(1));
  333.     update(0,(x==floatOf(whnf) ? cfunTrue : cfunFalse));
  334.     ret();
  335. }
  336. End
  337.  
  338. static comb2(pr_LeFloat)        /* float <= primitive           */
  339. {   Float x;
  340.     eval(offset(2));
  341.     x = floatOf(whnf);
  342.     eval(offset(1));
  343.     update(0,(x<=floatOf(whnf) ? cfunTrue : cfunFalse));
  344.     ret();
  345. }
  346. End
  347.  
  348. /* --------------------------------------------------------------------------
  349.  * Generic comparison primitives:
  350.  *
  351.  * The following primitives are provided for the benefit of anyone that
  352.  * wants to use Gofer's generic comparison functions in place of the
  353.  * type class alternative.  Be warned however, that an attempt to compare
  354.  * two function values using these routines will generate a runtime error
  355.  * which will not be trapped unless you compile the runtime system and
  356.  * application with ARGCHECK=1 (in which case, the overall performance
  357.  * will degrade, even if you never actually do compare function values).
  358.  * You see, using type classes really can bring benefits ...       :-)
  359.  *
  360.  * (The hardest thing in the following code is ensuring that all of the
  361.  * appropriate temporary variables stay on the stack to ensure proper
  362.  * operation of the garbage collector.)
  363.  * ------------------------------------------------------------------------*/
  364.  
  365. #define LT 0
  366. #define EQ 1
  367. #define GT 2
  368.  
  369. static Int compare() {            /* Shared auxiliary function       */
  370.     StackPtr args = sp;            /* for generic comparisons       */
  371.     Int      xy;
  372.  
  373.     pushed(1) = pair(pushed(1),cfunNil);/* turn arguments into lists       */
  374.     pushed(0) = pair(pushed(0),cfunNil);/* simulating depth-first stack       */
  375.  
  376.     do {
  377.     Int xdepth, ydepth;
  378.  
  379.     eval(fst(pushed(0)));        /* evaluate part of `x'           */
  380.         push(whnf);
  381.     xdepth = pushedSince(args);
  382.  
  383.     eval(fst(pushed(1+xdepth)));    /* evaluate part of `y'           */
  384.     push(whnf);
  385.     ydepth = pushedSince(args) - xdepth;
  386.  
  387.     xy         = xdepth+ydepth;    /* discard values on top of depth- */
  388.     pushed(xy)   = snd(pushed(xy));    /* first stacks               */
  389.     pushed(xy+1) = snd(pushed(xy+1));
  390.  
  391.         /* If the whnf of the part of x is   X x1 ... xn
  392.      * and the whnf of the part of y is  Y y1 ... ym,
  393.      * then the top of the stack will look like this:
  394.      *
  395.      *    top() =    Y  \
  396.      *        y1  |
  397.      *        .   |    ydepth elements
  398.      *        .   |
  399.      *        ym /
  400.      *        X  \
  401.      *        x1  |
  402.      *        .   |    xdepth elements
  403.      *        .   |
  404.      *        xn /
  405.      *        xs
  406.      *        ys
  407.      */
  408.  
  409.     if (isPair(top()) || isPair(pushed(ydepth))) {
  410.         if (isPair(top()) && fst(top())==FLOATCELL) {    /* Floats  */
  411.         Float xf = floatOf(pushed(ydepth));
  412.         Float yf = floatOf(top());
  413.         if (xf<yf) return LT;
  414.         if (xf>yf) return GT;
  415.         }
  416.         else {                        /* Ints       */
  417.         Int xi = intOf(pushed(ydepth));
  418.         Int yi = intOf(top());
  419.         if (xi<yi) return LT;
  420.         if (xi>yi) return GT;
  421.         }
  422.     }
  423.     else {                /* two proper constructor applics  */
  424.         if (top()>pushed(ydepth))    /* x structure has smaller constr  */
  425.         return LT;
  426.         if (top()<pushed(ydepth))    /* y structure has smaller constr  */
  427.         return GT;
  428.         if (xdepth!=ydepth)
  429.         abandon("type error in comparison");
  430.         else {
  431.         Int i;
  432.         for (i=ydepth-1; i>0; --i) {        /* add new values  */
  433.             pushed(xy+1) = pair(pushed(i),pushed(xy+1));
  434.             pushed(xy)   = pair(pushed(i+ydepth),pushed(xy));
  435.         }
  436.         }
  437.     }
  438.     sp = args;
  439.     } while (isPair(top()));        /* loop if value queue not empty*/
  440.  
  441.     return EQ;                /* everything matched, so x==y  */
  442. }
  443.  
  444. #define genericPrim(n,bool)    static comb2(n)                   \
  445.                     update(0,bool ? cfunTrue : cfunFalse); \
  446.                     ret();                   \
  447.                 End
  448. genericPrim(pr_GenericEq, compare()==EQ)
  449. genericPrim(pr_GenericNe, compare()!=EQ)
  450. genericPrim(pr_GenericLt, compare()==LT)
  451. genericPrim(pr_GenericLe, compare()!=GT)
  452. genericPrim(pr_GenericGt, compare()==GT)
  453. genericPrim(pr_GenericGe, compare()!=LT)
  454. #undef genericPrim
  455.  
  456. /* --------------------------------------------------------------------------
  457.  * Print primitives:
  458.  * ------------------------------------------------------------------------*/
  459.  
  460. static comb3(pr_ShowsInt)        /* find string rep. for integer       */
  461. {   Int num;                /*  :: Int -> Int -> ShowS       */
  462.     drop();                /* throw away first parameter       */
  463.     eval(pop());
  464.     num = whnfInt;
  465.  
  466.     if (0<=num && num<10) {                /* single digit       */
  467.     updap(0,consCharArray['0'+num],top());
  468.     }
  469.     else if (num<0) {                    /* negative integer*/
  470.     num = -num;
  471.     do {
  472.         heap(1);
  473.         topfun(consCharArray['0'+num%10]);
  474.     } while ((num/=10)>0);
  475.     updap(0,consCharArray['-'],top());
  476.     }
  477.     else {                        /* positive integer*/
  478.     do {
  479.         heap(1);
  480.         topfun(consCharArray['0'+num%10]);
  481.     } while ((num/=10)>9);
  482.     updap(0,consCharArray['0'+num],top());
  483.     }
  484.     ret();
  485. }
  486. End
  487.  
  488. static comb3(pr_ShowsFloat)        /* find string rep. for float       */
  489. {   String s;                /*  :: Int -> Float -> ShowS       */
  490.     Int    n;
  491.     drop();                /* throw away first parameter       */
  492.     eval(pop());
  493.     s = floatToString(floatOf(whnf));
  494.     n = strlen(s);
  495.     while (1<n--) {
  496.     heap(1);
  497.     topfun(consCharArray[s[n]]);
  498.     }
  499.     updap(0,consCharArray[*s],top());
  500.     ret();
  501. }
  502. End
  503.  
  504. /* --------------------------------------------------------------------------
  505.  * Storage, initialisation and marking of primitives:
  506.  * ------------------------------------------------------------------------*/
  507.  
  508. Cell primFatbar,     primFail;        /* System (internal) primitives       */
  509. Cell primUndefMem,   primBlackHole;
  510. Cell primSel,         primIf;
  511. Cell primStrict;
  512.  
  513. Cell primPlusInt,    primMinusInt;    /* User (general) primitives       */
  514. Cell primMulInt,     primDivInt;
  515. Cell primModInt,     primRemInt;
  516. Cell primNegInt,     primQuotInt;
  517. Cell primCharToInt,  primIntToChar;
  518. Cell primIntToFloat;
  519. Cell primPlusFloat,  primMinusFloat;
  520. Cell primMulFloat,   primDivFloat;
  521. Cell primNegFloat;
  522. Cell primEqInt,         primLeInt;
  523. Cell primEqChar,     primLeChar;
  524. Cell primEqFloat,    primLeFloat;
  525. Cell primGenericEq,  primGenericNe;
  526. Cell primGenericGt,  primGenericGe;
  527. Cell primGenericLt,  primGenericLe;
  528. Cell primShowsInt,   primShowsFloat;
  529. Cell primError;
  530.  
  531. #if  HAS_FLOATS
  532. Cell primSinFloat,   primAsinFloat;
  533. Cell primCosFloat,   primAcosFloat;
  534. Cell primTanFloat,   primAtanFloat;
  535. Cell primAtan2Float, primExpFloat;
  536. Cell primLogFloat,   primLog10Float;
  537. Cell primSqrtFloat,  primFloatToInt;
  538. #endif
  539.  
  540. Cell primFopen;                /* read from file primitive       */
  541.  
  542. static Void primInit() {        /* initialise primitives       */
  543.     primFatbar       = mkSuper(pr_FATBAR);
  544.     primFail       = mkSuper(pr_FAIL);
  545.     primUndefMem   = mkSuper(pr_UNDEFMEM);
  546.     primBlackHole  = mkSuper(pr_BlackHole);
  547.     primSel       = mkSuper(pr_SEL);
  548.     primIf       = mkSuper(pr_IF);
  549.     primStrict       = mkSuper(pr_STRICT);
  550.     primPlusInt       = mkSuper(pr_PlusInt);
  551.     primMinusInt   = mkSuper(pr_MinusInt);
  552.     primMulInt       = mkSuper(pr_MulInt);
  553.     primDivInt       = mkSuper(pr_DivInt);
  554.     primQuotInt       = mkSuper(pr_QuotInt);
  555.     primModInt       = mkSuper(pr_ModInt);
  556.     primRemInt       = mkSuper(pr_RemInt);
  557.     primNegInt       = mkSuper(pr_NegInt);
  558.     primCharToInt  = mkSuper(pr_CharToInt);
  559.     primIntToChar  = mkSuper(pr_IntToChar);
  560.     primIntToFloat = mkSuper(pr_IntToFloat);
  561.     primPlusFloat  = mkSuper(pr_PlusFloat);
  562.     primMinusFloat = mkSuper(pr_MinusFloat);
  563.     primMulFloat   = mkSuper(pr_MulFloat);
  564.     primDivFloat   = mkSuper(pr_DivFloat);
  565.     primNegFloat   = mkSuper(pr_NegFloat);
  566.     primEqInt       = mkSuper(pr_EqInt);
  567.     primLeInt       = mkSuper(pr_LeInt);
  568.     primEqChar       = mkSuper(pr_EqChar);
  569.     primLeChar       = mkSuper(pr_LeChar);
  570.     primEqFloat       = mkSuper(pr_EqFloat);
  571.     primLeFloat       = mkSuper(pr_LeFloat);
  572.     primGenericEq  = mkSuper(pr_GenericEq);
  573.     primGenericNe  = mkSuper(pr_GenericNe);
  574.     primGenericGt  = mkSuper(pr_GenericGt);
  575.     primGenericGe  = mkSuper(pr_GenericGe);
  576.     primGenericLt  = mkSuper(pr_GenericLt);
  577.     primGenericLe  = mkSuper(pr_GenericLe);
  578.     primShowsInt   = mkSuper(pr_ShowsInt);
  579.     primShowsFloat = mkSuper(pr_ShowsFloat);
  580.     primError      = mkSuper(pr_Error);
  581.     primInput       = mkSuper(pr_Input);
  582.     primFopen      = mkSuper(pr_Fopen);
  583. #if HAS_FLOATS
  584.     primSinFloat   = mkSuper(pr_SinFloat);
  585.     primAsinFloat  = mkSuper(pr_AsinFloat);
  586.     primCosFloat   = mkSuper(pr_CosFloat);
  587.     primAcosFloat  = mkSuper(pr_AcosFloat);
  588.     primTanFloat   = mkSuper(pr_TanFloat);
  589.     primAtanFloat  = mkSuper(pr_AtanFloat);
  590.     primAtan2Float = mkSuper(pr_Atan2Float);
  591.     primExpFloat   = mkSuper(pr_ExpFloat);
  592.     primLogFloat   = mkSuper(pr_LogFloat);
  593.     primLog10Float = mkSuper(pr_Log10Float);
  594.     primSqrtFloat  = mkSuper(pr_SqrtFloat);
  595.     primFloatToInt = mkSuper(pr_FloatToInt);
  596. #endif
  597. }
  598.  
  599. static Void primMark() {        /* mark primitives           */
  600.     mark(primFatbar);
  601.     mark(primFail);
  602.     mark(primUndefMem);
  603.     mark(primBlackHole);
  604.     mark(primSel);
  605.     mark(primIf);
  606.     mark(primStrict);
  607.     mark(primPlusInt);
  608.     mark(primMinusInt);
  609.     mark(primMulInt);
  610.     mark(primDivInt);
  611.     mark(primQuotInt);
  612.     mark(primModInt);
  613.     mark(primRemInt);
  614.     mark(primNegInt);
  615.     mark(primCharToInt);
  616.     mark(primIntToChar);
  617.     mark(primIntToFloat);
  618.     mark(primPlusFloat);
  619.     mark(primMinusFloat);
  620.     mark(primMulFloat);
  621.     mark(primDivFloat);
  622.     mark(primNegFloat);
  623.     mark(primEqInt);
  624.     mark(primLeInt);
  625.     mark(primEqChar);
  626.     mark(primLeChar);
  627.     mark(primEqFloat);
  628.     mark(primLeFloat);
  629.     mark(primGenericEq);
  630.     mark(primGenericNe);
  631.     mark(primGenericGt);
  632.     mark(primGenericGe);
  633.     mark(primGenericLt);
  634.     mark(primGenericLe);
  635.     mark(primShowsInt);
  636.     mark(primShowsFloat);
  637.     mark(primError);
  638.     mark(primInput);
  639.     mark(primFopen);
  640. #if HAS_FLOATS
  641.     mark(primSinFloat);
  642.     mark(primAsinFloat);
  643.     mark(primCosFloat);
  644.     mark(primAcosFloat);
  645.     mark(primTanFloat);
  646.     mark(primAtanFloat);
  647.     mark(primAtan2Float);
  648.     mark(primExpFloat);
  649.     mark(primLogFloat);
  650.     mark(primLog10Float);
  651.     mark(primSqrtFloat);
  652.     mark(primFloatToInt);
  653. #endif
  654. }
  655.  
  656. /* --------------------------------------------------------------------------
  657.  * Main program including startup code and initialisation:
  658.  *